package com.csap.framework.boot.apidoc.autoconfigure;

import com.csap.framework.apidoc.CsapResourcesProvider;
import com.csap.framework.apidoc.DefaultDevtoolsClass;
import com.csap.framework.apidoc.DevtoolsClass;
import com.csap.framework.apidoc.GlobalCsapRequestParamProvider;
import com.csap.framework.apidoc.config.ScannerPackageConfig;
import com.csap.framework.apidoc.properties.CsapDocConfig;
import com.csap.framework.apidoc.service.CsapDocService;
import com.csap.framework.apidoc.web.CsapDocController;
import com.csap.framework.validation.factory.ValidateFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * apidoc config
 *
 * @author yangchengfu
 * @date 2020/1/3 10:16 上午
 **/
@Configuration
@EnableConfigurationProperties({CsapDocConfig.class})
@ComponentScan
public class ApidocAutoConfiguration {
    @Bean
    public RunApplicationListener runApplicationListener() {
        return new RunApplicationListener();
    }

    @Bean
    public ScannerPackageConfig scannerPackageConfig(CsapDocConfig csapDocConfig, ObjectProvider<EnableApidocConfig> enableApidocConfig) {
        EnableApidocConfig enableApidocConfig1 = enableApidocConfig.getIfAvailable(EnableApidocConfig::new);
        csapDocConfig.setModelPackages(enableApidocConfig1.getModelPackages());
        csapDocConfig.setApiPackages(enableApidocConfig1.getApiPackages());
        csapDocConfig.setEnumPackages(enableApidocConfig1.getEnumPackages());
        return new ScannerPackageConfig(csapDocConfig);
    }

    @Bean
    @ConditionalOnMissingBean
    public DevtoolsClass devtoolsClass() {
        return new DefaultDevtoolsClass();
    }

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Bean
    @ConditionalOnBean(CsapResourcesProvider.class)
    public CsapDocService csapDocService(CsapResourcesProvider csapResourcesProvider, ScannerPackageConfig scannerPackageConfig, ObjectProvider<ValidateFactory> validateFactory, DevtoolsClass devtoolsClasses) {
        return new CsapDocService(csapResourcesProvider, scannerPackageConfig, validateFactory.getIfAvailable(), devtoolsClasses);
    }

    @Bean
    @ConditionalOnMissingBean(CsapResourcesProvider.class)
    public CsapDocService csapBaseDocService(ScannerPackageConfig scannerPackageConfig, ObjectProvider<ValidateFactory> validateFactory, DevtoolsClass devtoolsClasses) {
        return new CsapDocService(() -> scannerPackageConfig.getConfig().getDocResources(), scannerPackageConfig, validateFactory.getIfAvailable(), devtoolsClasses);
    }

    @Bean
    @ConditionalOnBean(GlobalCsapRequestParamProvider.class)
    public CsapDocController csapDocController2(CsapDocService csapDocService, ObjectProvider<GlobalCsapRequestParamProvider> globalCsapDocModelProvider) {
        return new CsapDocController(csapDocService.globalRequestParam(globalCsapDocModelProvider.getIfAvailable().get()));
    }

    @Bean
    @ConditionalOnMissingBean(GlobalCsapRequestParamProvider.class)
    public CsapDocController csapDocController(CsapDocService csapDocService) {
        return new CsapDocController(csapDocService.globalRequestParam(GlobalCsapRequestParamProvider.defaultParam()));
    }
}
